package infiews.web;

import infiews.crawler.Crawler;
import infiews.fetch.PageFetcher;

import java.io.InputStream;
import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.List;

public class Page {
	
	private String url;
	
	private String html;

	// Data for textual content
	private String text;
	private String title;
//	private int parentID;
    private int parentId;

	private int id;
	private int deep = 0;
	private boolean mustSave = true;

	private String lastModified;
	
	// binary data (e.g, image content)
	// It's null for html pages
	private byte[] binaryData;

	private List<String> urls;

	private ByteBuffer bBuf;
    private String site;

	private String usefulContent;

	private final static String defaultEncoding = Crawler.getCurrentSite().getEncoding();

    public Page(String url) {
        this.url = url;
        this.site = Crawler.currentSiteName;
	}

    public Page( String url, String html, int parentId, String siteName, String lastModif, int deep, int id){
        this.url = url;
        this.parentId = parentId;
        this.site = siteName;
        this.lastModified = lastModif;
        this.id = id;
        this.deep = deep;
    }

  /*  public Page(String url,int parentId){
        this.url = url;
        this.parentId = parentId;
        this.site = Crawler.currentSite;
    }*/

	public boolean load(final InputStream in, final int totalsize,
			final boolean isBinary) {
		if (totalsize > 0) {
			this.bBuf = ByteBuffer.allocate(totalsize + 1024);
		} else {
			this.bBuf = ByteBuffer.allocate(PageFetcher.MAX_DOWNLOAD_SIZE);
		}
		final byte[] b = new byte[1024];
		int len;
		double finished = 0;
		try {
			while ((len = in.read(b)) != -1) {
				if (finished + b.length > this.bBuf.capacity()) {
					break;
				}
				this.bBuf.put(b, 0, len);
				finished += len;
			}
		} catch (final BufferOverflowException boe) {
            // TODO: log this, do not output this to console
			System.out.println("Page size exceeds maximum allowed.");
			return false;
		} catch (final Exception e) {
            // TODO: Log this, do not output this to console
			System.err.println(e.getMessage());
			return false;
		}

		this.bBuf.flip();
		if (isBinary) {
			binaryData = new byte[bBuf.limit()];
			bBuf.get(binaryData);
		} else {
			this.html = "";
			this.html += Charset.forName(defaultEncoding).decode(this.bBuf);
			this.bBuf.clear();
			if (this.html.length() == 0) {
				return false;
			}
		}
		return true;
	}

	public void setHTML( String content ){
		this.html = content;
	}
	

	public int getParentId(){
		return parentId;
	}

    public void setDeep( int deep ){
		this.deep = deep;
	}

	public int getDeep(){
		return deep;
	}


	public String getSite(){
		return site;
	}

	/*public int getParentID(){
		return parentID;
	} */
	
	public String getHTML() {
		return this.html;
	}

	/*public String getText() {
		return text;
	}*/

	/*public void setText(String text) {
		this.text = text;
	}*/

	/*public String getTitle() {
		return title;
	}*/

	/*public void setTitle(String title) {
		this.title = title;
	}*/

	/*public List<String> getURLs() {
		return urls;
	}*/

	public void setURLs(List<String> urls) {
		this.urls = urls;
	}

	public String getURL() {
		return url;
	}

	public Boolean equals( Page oPage ){
		return this.getURL().equals(oPage.getURL());
	}
	
	public void setURL(String url) {
		this.url = url;
	}

	// Image or other non-textual pages
	public boolean isBinary() {
		return binaryData != null;
	}

	public byte[] getBinaryData() {
		return binaryData;
	}

	public String getLastModified() {
		return lastModified;
	}
	
	public void setLastModified( String newLastModified ) {
		lastModified = newLastModified;
	}
	
	public int getId(){
		return id;
	}

	public boolean isMustSave(){
		return mustSave;
	}

	public void setIsMustSave(boolean mustSave){
		this.mustSave = mustSave;
	}

	public String getUsefulContent(){
		return usefulContent;
	}

	public void setUsefulContent(String content){
		usefulContent = content;
	}
	
}
